﻿using System;
using System.Collections.Generic;
using System.Linq;
using EscapeZone.Components;
using EscapeZone.Screens;
using EscapeZone.Weapons;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using XnaPlus.Common.Extensions;
using XnaPlus.Common.Visual;

namespace EscapeZone
{
    public class Player : DrawableEscapeGameComponent, IAnimationHook
    {
        public int Score { get; set; }
        private Animation m_animation;

        public Pistol Weapon { get; set; }

        public Vector2 Position { get; set; }

        private List<Projectile> m_projectiles;


        public bool Centered
        {
            get { return true; }
        }

        private Vector2 m_instantVelocity;

        public Rectangle Rect { get { return new Rectangle((int) (Position.X - m_animation.Size.X/2), (int) (Position.Y - m_animation.Size.Y/2), m_animation.Size.X, m_animation.Size.Y); } }

        public Player(Vector2 initialPosition, EscapeGame game, GameScreen screen) : base(game, screen)
        {
            Position = initialPosition;
            Score = 0;
            m_animation = new Animation(game, Art.Player, new Point(3, 1), Game.SpriteBatch, this)
                              {
                                  IsLooping = true,
                                  UpdateDelay = TimeSpan.FromMilliseconds(200),
                                  Scale = 2f
                              };

            Weapon = new Pistol(game, screen)
                         {
                             Ammo = 9999
                         };

            m_projectiles = new List<Projectile>();
        }

        protected override void HandleInput(GameTime gameTime)
        {
            base.HandleInput(gameTime);
            m_instantVelocity = Vector2.Zero;
            float velocity = Game.InputState.IsKeyDown(Keys.LeftShift) ? 1.0f : 5.0f;

            if (Game.InputState.IsKeyDown(Keys.A))
            {
                m_instantVelocity += new Vector2(-1 * velocity, 0);
            }

            if (Game.InputState.IsKeyDown(Keys.S))
            {
                m_instantVelocity += new Vector2(0, 1 * velocity);
            }

            if (Game.InputState.IsKeyDown(Keys.D))
            {
                m_instantVelocity += new Vector2(1 * velocity, 0);
            }

            if (Game.InputState.IsKeyDown(Keys.W))
            {
                m_instantVelocity += new Vector2(0, -1 * velocity);
            }

            m_instantVelocity = m_instantVelocity.Unit()*velocity;

            if (Game.InputState.CurrentMouseState.LeftButton == ButtonState.Pressed && Weapon != null)
            {
                var projectile = Weapon.Fire(Position, (Game.InputState.MousePosition.ToVector() - Position).Theta(), gameTime);
                if(projectile != null)
                {
                    m_projectiles.Add(projectile);
                }
            }
        }
        
       

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            var gameScreen = Screen as GameScreen;

            var rectX = Rect.Offset(new Vector2(m_instantVelocity.X, 0));
            if (gameScreen.Map.IntersectsWall(rectX))
                m_instantVelocity.X = 0;

            var rectY = Rect.Offset(new Vector2(0, m_instantVelocity.Y));
            if (gameScreen.Map.IntersectsWall(rectY))
                m_instantVelocity.Y = 0;

            Position += m_instantVelocity;

            m_animation.Animating = m_instantVelocity != Vector2.Zero;

            if (m_animation.Animating)
            {
                m_animation.Orientation = (float) (m_instantVelocity.Theta() + Math.PI/2);
            }

            m_projectiles.RemoveAll(p => !p.Enabled);

            m_instantVelocity = Vector2.Zero;

        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                m_animation.Dispose();
                m_animation = null;
            }

            base.Dispose(disposing);
        }

        public override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);
            m_animation.Draw(gameTime);

            foreach (Projectile projectile in m_projectiles.Where(p => p.Visible))
            {
                projectile.Draw(gameTime);
            }
        }

        
    }
}